﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using General.Core.Config;
using General.Core.Data;
using General.Entities.Data;
using General.Entities.Models;
using General.Entities.ViewData.Role;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;

namespace General.Services.Role
{
    public class RoleService : IRoleService
    {
        private readonly IMemoryCache memoryCache;
        private readonly IRepository<tc_role> tc_RoleRepository;
        private readonly IRepository<tc_authority> tc_AuthorityRepository;

        public RoleService(IMemoryCache memoryCache, IRepository<tc_role> tc_roleRepository,
            IRepository<tc_authority> tc_authorityRepository)
        {
            this.memoryCache = memoryCache;
            tc_RoleRepository = tc_roleRepository;
            tc_AuthorityRepository = tc_authorityRepository;
        }


        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<RoleModel>> GetAllList()
        {
            var res = await tc_RoleRepository.GetAllAsync().OrderBy(x => x.id).ToListAsync();
            var list = new List<RoleModel>();
            foreach (var item in res)
            {
                RoleModel temp = new RoleModel()
                {
                    name = item.rolename,
                    value = item.id
                };
                list.Add(temp);
            }
            return list;
        }


        /// <summary>
        /// 获取所有角色数据写入内存
        /// </summary>
        /// <returns></returns>
        public async Task GetDataWriteMemory()
        {
            var res = await tc_RoleRepository.GetAllAsync().OrderBy(x => x.id).ToListAsync();
            memoryCache.Set(GobalConfig.SYSTEM_ROLELISTMEMORYKEY_STRING, JsonHelper.Serialize(res));
        }

        /// <summary>
        /// 根据id列表获取role列表
        /// </summary>
        /// <param name="uids"></param>
        /// <returns></returns>
        public async Task<List<tc_role>> GetListByIds(string uids)
        {
            var arr = uids.Split(",", StringSplitOptions.RemoveEmptyEntries);
            var arrints = arr.Select<string, int>(x => Convert.ToInt32(x));

            List<tc_role> list = await tc_RoleRepository.GetAllAsync(x => arrints.Contains(x.id)).ToListAsync();
            return list;
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="rolename"></param>
        /// <param name="rolecode"></param>
        /// <param name="remark"></param>
        /// <returns></returns>
        public async Task<AdminResult> GetList(int page, int limit, string rolename, string rolecode, string remark)
        {
            AdminResult result = new AdminResult();
            var query = from d in tc_RoleRepository.Table
                        orderby d.id //descending
                        select new tc_role()
                        {
                            createtime = d.createtime,
                            id = d.id,
                            remark = d.remark,
                            rolecode = d.rolecode,
                            rolename = d.rolename,
                             updatetime = d.updatetime
                        };
            if (!string.IsNullOrWhiteSpace(rolename))
            {
                query = query.Where(x => x.rolename.Contains(rolename));
            }
            if (!string.IsNullOrWhiteSpace(rolecode))
            {
                query = query.Where(x => x.rolecode.Contains(rolecode));
            }
            if (!string.IsNullOrWhiteSpace(remark))
            {
                query = query.Where(x => x.remark.Contains(remark));
            }
            result.count = await query.CountAsync();
            result.data = await query.Skip((page - 1) * limit).Take(limit).ToListAsync();
            result.code = 0;
            return result;
        }



        /// <summary>
        /// 增加信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task AddInfo(tc_role model)
        {
            model.permission = "";
            model.createtime = DateTime.Now;
            model.updatetime = DateTime.Now;
            await tc_RoleRepository.insertAsync(model);

            await GetDataWriteMemory();
        }


        /// <summary>
        /// 删除信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<int> DeleteInfo(string ids)
        {
            var arr = ids.Split(",", StringSplitOptions.RemoveEmptyEntries).Select<string, int>(x => Convert.ToInt32(x));
            var list = await tc_RoleRepository.GetAllAsync(x => arr.Contains(x.id)).ToListAsync();

            await GetDataWriteMemory();
            return await tc_RoleRepository.DeleteListAsync(list);
        }

        /// <summary>
        /// 修改信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="role"></param>
        /// <returns></returns>
        public async Task EditInfo(int id, tc_role role)
        {
            var model = await tc_RoleRepository.getByIdAsync(id);
            model.remark = role.remark;
            model.rolecode = role.rolecode;
            model.rolename = role.rolename;
            model.updatetime = DateTime.Now;
            await tc_RoleRepository.UpdateAsync(model);

            await GetDataWriteMemory();
        }

        /// <summary>
        /// 修改角色权限信息
        /// </summary>
        /// <returns></returns>
        public async Task EditPermissionInfo(int id, string data)
        {
            var model = await tc_RoleRepository.getByIdAsync(id);
            model.permission = data;
            await tc_RoleRepository.UpdateAsync(model);
            await GetDataWriteMemory();
        }


        /// <summary>
        /// 根据id获取权限功能id列表
        /// </summary>
        /// <param name="roleid"></param>
        /// <returns></returns>
        public async Task<List<int>> GetPermissionById(int roleid)
        {
            var result = await tc_RoleRepository.getByIdAsync(roleid);
            var data = result.permission.Split(",", StringSplitOptions.RemoveEmptyEntries).Select<string, int>(x => Convert.ToInt32(x)).ToList();
            return data;
        }

        //用于遍历功能列表
        private int ergodicSeed = 1;
        private List<PermissionmModel> permissionmModel;
        private List<tc_authority> ergodicAuthority; //当前层级的父级数据


        /// <summary>
        /// 获取角色权限配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<PermissionmModel>> GetPermissionmData(int roleid)
        {
            //获取功能列表
            var authorityList = await tc_AuthorityRepository.GetAllAsync().ToListAsync();
            ergodicSeed = 1;
            permissionmModel = new List<PermissionmModel>();
            var rolePermissionList = await GetPermissionById(roleid);
            ErgodicPermissionm(authorityList, rolePermissionList);

            return permissionmModel;
        }

        /// <summary>
        /// 遍历功能方法
        /// </summary>
        /// <param name="model"></param>
        public void ErgodicPermissionm(List<tc_authority> list,List<int> rolePermissionList)
        {
            if (ergodicSeed == 1) //父级
            {
                ergodicAuthority = new List<tc_authority>();
                //增加数据
                ergodicAuthority.AddRange(list.Where(x=>x.parentId == -1 || x.parentId == null).ToList());
                foreach (var item in ergodicAuthority)
                {
                    var temp = new PermissionmModel()
                    {
                        id = Convert.ToInt32(item.id),
                        field = item.authority,
                        spread = true,
                        title = item.authorityName,
                        ischecked = rolePermissionList.Contains(Convert.ToInt32(item.id))&&item.isMenu == 1 ? true :null,
                        children = new List<PermissionmModel>()
                    };
                    permissionmModel.Add(temp);
                }
            }
            else
            {
                var tempergodicAuthority = new List<tc_authority>();
                foreach (var item in ergodicAuthority)
                {
                    var ChildrenAuthorityList = list.Where(x => x.parentId == item.id).ToList();
                    tempergodicAuthority.AddRange(ChildrenAuthorityList);
                    foreach (var childrenItem in ChildrenAuthorityList)
                    {

                        // ------------
                        if (ergodicSeed >= 2)
                        {
                            foreach (var pModel in permissionmModel)
                            {
                                if (pModel.id == childrenItem.parentId)
                                {
                                    var temp = new PermissionmModel()
                                    {
                                        id = Convert.ToInt32(childrenItem.id),
                                        field = childrenItem.authority,
                                        spread = true,
                                        title = childrenItem.authorityName,
                                        ischecked = rolePermissionList.Contains(Convert.ToInt32(childrenItem.id)) && childrenItem.isMenu == 1 ? true : null, children = new List<PermissionmModel>()
                                    };
                                    pModel.children.Add(temp);
                                }
                                if (ergodicSeed == 3)
                                {
                                    if (pModel.children == null) continue;
                                    foreach (var c1 in pModel.children)
                                    {
                                        if (c1.id == childrenItem.parentId)
                                        {
                                            var temp = new PermissionmModel()
                                            {
                                                id = Convert.ToInt32(childrenItem.id),
                                                field = childrenItem.authority,
                                                spread = true,
                                                title = childrenItem.authorityName,
                                                ischecked = rolePermissionList.Contains(Convert.ToInt32(childrenItem.id)) && childrenItem.isMenu == 1 ? true : null,
                                                children = new List<PermissionmModel>()
                                            };
                                            c1.children.Add(temp);
                                        }
                                    }
                                }
                                 
                               
                            }
                        }
                        //------------
                        

                        
                    }
                }
                ergodicAuthority = tempergodicAuthority;
            }

            //没有数据，遍历结束
            if (!ergodicAuthority.Any())
            {
                return;
            }
            ergodicSeed++;
            ErgodicPermissionm(list, rolePermissionList);
        }

    }
}
